﻿using System;

namespace MathMethods
{
    /// <summary>
    /// Матрица заданного размера
    /// </summary>
    public class Matrix
    {
        /// <summary>
        /// Массив строк
        /// </summary>
        private Row[] rows;

        /// <summary>
        /// Количество строк
        /// </summary>
        public int rowCount;

        /// <summary>
        /// Количество столбцов
        /// </summary>
        public int colCount;

        /// <summary>
        /// Клонирует матрицу
        /// </summary>
        /// <returns>колнированная матрица</returns>
        public Matrix Clone()
        {
            Matrix tmp = new Matrix(colCount, rowCount);
            for (int i = 0; i < tmp.rowCount; i++)
                tmp[i] = rows[i].Clone();
            return tmp;
        }

        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="colNum">число столбцов</param>
        /// <param name="rowNum">число строк</param>
        public Matrix(int colNum, int rowNum)
        {
            rows = new Row[rowNum];
            rowCount = rowNum;
            colCount = colNum;

            for (int i = 0; i < rowNum; i++)
                rows[i] = new Row(colNum);
        }

        public Matrix()
        {

        }

        /// <summary>
        /// Переставить строки местами
        /// </summary>
        /// <param name="i">номер первой строки</param>
        /// <param name="j">номер второй строки</param>
        public void ExchangeRows(int i, int j)
        {
            Row tmp = rows[i];
            rows[i] = rows[j];
            rows[j] = tmp;
        }

        /// <summary>
        /// Переставить колонки местами
        /// </summary>
        /// <param name="c1">номер первой колонки</param>
        /// <param name="c2">номер второй колонки</param>
        public void ExchangeColumns(int c1, int c2)
        {
            for (int i = 0; i < rowCount; i++)
                rows[i].Exchange(c1, c2);
        }

        /// <summary>
        /// Обращение к строке матрицы
        /// </summary>
        /// <param name="i">номер строки</param>
        /// <returns>строку матрицы</returns>
        public Row this[int i]
        {
            set
            {
                rows[i] = value;
            }

            get
            {
                return rows[i];
            }
        }

        /// <summary>
        /// Обращение к элементу матрицы
        /// </summary>
        /// <param name="i">
        /// номер строки в которой расположен элемент</param>
        /// <param name="j">
        /// номер столбца в которой расположен элемент</param>
        /// <returns>значение элемента матрицы</returns>
        public double this[int i, int j]
        {
            set
            {
                rows[i][j] = value;
            }
            get
            {
                return rows[i][j];
            }
        }
    }
}
